﻿@using Gurux.DLMS.AMI.Script
@using Gurux.DLMS.AMI.Shared
@using Gurux.DLMS.AMI.Shared.DIs
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using Gurux.DLMS.AMI.Shared.DTOs
@using Gurux.DLMS.AMI.Shared.Rest
@using Gurux.DLMS.AMI.Shared.Enums
@using Gurux.DLMS.AMI.Module
@using System.Globalization
@using System.Text
@using System.Text.Json
@using Gurux.DLMS.AMI.Script.Pages
@using Microsoft.AspNetCore.SignalR.Client
@using Microsoft.Extensions.Logging

@namespace Gurux.DLMS.AMI.Client.Pages.Config

@attribute [Authorize(Roles = GXRoles.Admin)]
@inject NavigationManager NavigationManager
@implements IDisposable
@inject HttpClient Http
@inject IGXNotifier Notifier
@implements IGXConfigUpdate

@if (_settings != null)
{
    <p>
        <MenuControl RightCorner=true>
            <ChildContent>
                <MenuItem Text="Run cron" Icon="oi oi-flash" OnClick="@OnRun" />
            </ChildContent>
        </MenuControl>
    </p>
    <p>
    </p>
    <EditForm Model="@_settings">
        <div class="row">
            <div style="width:100%">
                <div class="form-group">
                    <label>@Properties.Resources.LastExecutionTime</label>
                    @if (_settings.Run != null)
                    {
                        <input class="form-control" type="text" readonly="readonly" value="@_settings.Run.ToString()" />
                    }
                    else
                    {
                        <label>@Properties.Resources.Never</label>
                    }
                    <p></p>
                </div>
                <div class="form-group">
                    <label>Run cron every</label>
                    <select class="form-select" @bind="@_settings.Interval">
                        @foreach (var it in Intervals)
                        {
                            <option value="@it.Key">@it.Value</option>
                        }
                    </select>
                </div>
                <div class="form-group">
                    <label>Next estimated run time</label>
                    @if (_settings.EstimatedNextTime != null)
                    {
                        <input class="form-control" type="text" readonly="readonly" value="@_settings.EstimatedNextTime.ToString()" />
                    }
                    else
                    {
                        <label>@Properties.Resources.Never</label>
                    }
                </div>
            </div>
        </div>
    </EditForm>
}

@code {
    /// <summary>
    /// Parent component.
    /// </summary>
    [Parameter]
    public Gurux.DLMS.AMI.Client.Pages.Config.Configurations? Parent { get; set; }

    /// <inheritdoc/>
    public void Update()
    {
        if (!string.IsNullOrEmpty(Parent?.Active?.Settings))
        {
            _settings = JsonSerializer.Deserialize<CronSettings>(Parent.Active.Settings);
        }
        StateHasChanged();
    }

    Dictionary<int, string> Intervals = new Dictionary<int, string>();

    CronSettings? _settings;

    protected override void OnInitialized()
    {
        Intervals.Add(0, "Never");
        Intervals.Add(1, "1 hours");
        Intervals.Add(3, "3 hours");
        Intervals.Add(6, "6 hours");
        Intervals.Add(12, "12 hours");
        Intervals.Add(24, "1 day");
        Intervals.Add(24 * 7, "1 week");

        try
        {
            if (Notifier == null)
            {
                throw new ArgumentException(Properties.Resources.InvalidNotifier);
            }
            Notifier.ProgressStart();
            Notifier.ClearStatus();
            Notifier.On<IEnumerable<GXConfiguration>>(this, nameof(IGXHubEvents.ConfigurationSave), (configurations) =>
            {
                try
                {
                    if (configurations != null)
                    {
                        foreach (var it in configurations)
                        {
                            if (it.Name == GXConfigurations.Cron && !string.IsNullOrEmpty(it.Settings))
                            {
                                _settings = JsonSerializer.Deserialize<CronSettings>(it.Settings);
                                StateHasChanged();
                                break;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Notifier?.ProcessError(ex);
                }
            });
            Notifier.On(this, nameof(IGXHubEvents.CronCompleate), async () =>
            {
                try
                {
                    //Get configuration data.
                    GXConfiguration? tmp = (await Http.GetAsJsonAsync<GetConfigurationResponse>(string.Format("api/Configuration?id={0}", Parent?.Active.Id))).Item;
                    if (!string.IsNullOrEmpty(tmp?.Settings))
                    {
                        _settings = JsonSerializer.Deserialize<CronSettings>(tmp.Settings);
                        StateHasChanged();
                    }
                }
                catch (Exception ex)
                {
                    Notifier?.ProcessError(ex);
                }
            });
            Notifier.Clear();
            Notifier.AddMenuItem(new GXMenuItem() { Text = Properties.Resources.Save, Icon = "oi oi-pencil", OnClick = OnSave });
            Notifier.AddMenuItem(new GXMenuItem() { Text = Properties.Resources.Cancel, Icon = "oi oi-action-undo", OnClick = OnCancel });
            Notifier.UpdateButtons();
            if (!string.IsNullOrEmpty(Parent?.Active?.Settings))
            {
                _settings = JsonSerializer.Deserialize<CronSettings>(Parent.Active.Settings);
            }
        }
        catch (AccessTokenNotAvailableException exception)
        {
            exception.Redirect();
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
        finally
        {
            Notifier?.ProgressEnd();
        }
    }

    /// <summary>
    /// Save values.
    /// </summary>
    private async void OnSave()
    {
        Notifier?.ProgressStart();
        Notifier?.ClearStatus();
        try
        {
            if (Parent?.Active == null)
            {
                throw new Exception(Properties.Resources.InvalidTarget);
            }
            Parent.Active.Settings = JsonSerializer.Serialize(_settings);
            ConfigurationUpdate arg = new ConfigurationUpdate();
            arg.Configurations = new GXConfiguration[] { Parent.Active };
            await Http.PostAsJson("api/Configuration/Update", arg);
            ClientHelpers.NavigateToLastPage(NavigationManager, Notifier);
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
        finally
        {
            Notifier?.ProgressEnd();
        }
    }

    /// <summary>
    /// Run the cron.
    /// </summary>
    public async void OnRun()
    {
        Notifier?.ProgressStart();
        Notifier?.ClearStatus();
        try
        {
            ConfigurationRunCron req = new ConfigurationRunCron();
            await Http.PostAsJson<ConfigurationRunCronResponse>("api/Configuration/Cron", req);
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
        finally
        {
            Notifier?.ProgressEnd();
        }
    }

    /// <summary>
    /// Cancel update.
    ///</summary>
    private void OnCancel()
    {
        ClientHelpers.NavigateToLastPage(NavigationManager, Notifier);
    }

    public void Dispose()
    {
        Notifier.RemoveListener(this);
    }
}
